// *** Instructions à réaliser lors de "l'installation" du scripts ***
// *** Nécessite node.js ***
// npm install vcardparser
// npm install csvtojson

// Récupérer les arguments saisis au clavier

var fs = require('fs');
var vm = require('vm');

// Inclue le prototype Contact
vm.runInThisContext(fs.readFileSync(__dirname + "/contact.js"));

// Récupère le fichier donner en paramètre
var file = readVCard(process.argv.slice(1)[1]);

main(file);

//Fonction d'importation d'un fichier vcard
//Le paramètre ne peut être qu'UN SEUL FICHIER VCF
function readVCard (link) {
	if ( link == undefined ) {
		console.log("ERROR : le premier paramètre doit être un chemin vers un fichier .vcf");
		return false;
	}
	
	if ( link.split(".").pop() == "vcf" ) { 
		return link;
	}

	console.log("Erreur, format de fichier incorrect!")
	return false;
}

//Fonction pour convertir le contenu d'un fichier VCard en JSON
//Conversion pour UN SEUL fichier
function toJSON (fileName, callback) {
	var vCardParser = require('vcardparser');
	//Parser la vcard en JSON
	vCardParser.parseFile(fileName, function(err, json) {
    if ( err )
        return console.log(err);
    //On renvoie le résultat dans un callback
    callback(json);
	});
}

//Fonction pour vérifier que le format de pivot est respecté
//Le paramètre est le vcard converti en JSON
function sortJSON (jsonVCard) {
	//Vérifier que tous les champs du vcf sont bien renseignés
	if ( jsonVCard == undefined 
		|| jsonVCard.begin != "VCARD"
		|| jsonVCard.end != "VCARD"
		|| jsonVCard.n == undefined 
		|| jsonVCard.fn == undefined
		|| jsonVCard.tel == undefined
		|| jsonVCard.org == undefined
		|| jsonVCard.n.first == "" 
		|| jsonVCard.n.last == ""
		|| jsonVCard.fn == ""
		) {
		console.log("Le format de pivot n'est pas respecté, arrêt du programme!");
		process.exit();	
	}
	var contactVCard = new Contact(
		jsonVCard.n.last, 
		jsonVCard.n.first,
		jsonVCard.tel[0].value,
		jsonVCard.org.name,
		jsonVCard.fn
	);
	return contactVCard;
}

function main (filename, callback) {
	toJSON( filename, function( jsonVCard ) {
		//On vérifie que le vcard converti en JSON respecte le format de pivot
		var contactVCard = sortJSON(jsonVCard);
		//Faire la gestion des doublons
		findDoublons(contactVCard);
	});
}

//Fonction pour remonter les doublons 
function findDoublons (contactVCard, callback ) {
	//1)Charger le fichier Base.csv et tout stocker dans un tableau contenant des JSON
	//2)On a alors 1 tableau de JSON (contenant toutes les infos de Base.csv)
	//3)On compare chaque contact du tableau de JSON avec le vcard qu'on souhaite importer
	
	//On charge le fichier Base.csv
	loadCSV( function( tabJsonCsv ) {
		//Boucler sur le tableau JSON provenant du csv
		var hasDoublons = false;
		var j = 0;
		var c;

		while ( j<tabJsonCsv.length && !hasDoublons ) {
			c = new Contact(tabJsonCsv[j].nom, tabJsonCsv[j].prenom, tabJsonCsv[j].telephone, 
				tabJsonCsv[j].organisation, tabJsonCsv[j].fonction);
	
			//Comparer les noms et prénoms
			if ( c.firstName == contactVCard.firstName && c.lastName == contactVCard.lastName ) {
				hasDoublons = true;
			}
			j++;
		}

		//Action différente selon qu'on trouve un doublon ou non
		if ( hasDoublons ) {
			console.log("\nDonnées du contact déjà dans la base : \n");
			c.print();
			console.log("Données du contact en double : \n");
			contactVCard.print();

			//Fusion des données
			writeCSV(contactVCard, true);
		} else {
			//Ajout des données
			writeCSV(contactVCard, false);
		}
	});
}

//Fonction pour charge le fichier Base.csv dans un tableau de JSON
function loadCSV ( callback ) {
	var Converter = require("csvtojson").core.Converter;
	var fs = require("fs");

	var csvFileName = "Base.csv";
	var fileStream = fs.createReadStream(csvFileName);

	var csvConverter = new Converter({constructResult:true,delimiter:";"});

	csvConverter.on("end_parsed",function(jsonObj) {
		//callback pour récupérer le résultat du chargement du fichier Base.csv
	   	callback(jsonObj);
	});

	fileStream.pipe(csvConverter);	
}

function getContactLine (linesData, contactVCard) {
	var idx = 0;
	// pour chaque ligne (à partir de la 2e)
	var i = 1;

	// Dès que l'on trouve le contact, on arrête de chercher
	while ( i<linesData.length &&  idx==0 ) {
		// on récupère chaque donnée (séparée par des ;)
		var cols = linesData[i].split(';');

		if(cols[1] == contactVCard.firstName && cols[0] == contactVCard.lastName){
			idx = i;
		}
		i++;
	}
	return idx;
}

function processingContact (answer, data, contactVCard) {
	var linesData = data.split('\n');
	var idxContactLine = getContactLine(linesData, contactVCard);

	var colsData = linesData[idxContactLine].split(';')
	var contactBase = new Contact(colsData[0], colsData[1], colsData[2], colsData[3], colsData[4]);
	
	if ( answer == '1' ) {
		linesData[idxContactLine] = contactVCard.fusionAll(contactBase); 
	} else if ( answer == '2' ) {
		linesData[idxContactLine] = contactVCard.replaceAll(contactBase); 
	}

	//On join les données finales
	linesData = linesData.join('\n');
	//On écrit les données remplacées dans le fichier Base.csv
	fs.writeFile('Base.csv', linesData, function (err) {
		if (err) 
			return console.log(err);
		process.exit();
	});
}

//Fonction pour écrire les données d'un vcard dans le fichier central Base.csv
function writeCSV (contactVCard, replaceMode) {
	//Lecture du fichier
	fs.readFile('Base.csv', 'utf8', function (err,data) {
	  	if (err) {
	    	return console.log(err);
	 	}

		// mode remplacement = on va rechercher la ligne avec le même nom et prénom pour la fusionner ou la remplacer selon le choix de l'utilisateur
		if ( replaceMode ) {
			console.log("Un doublon a été détecté pour "+contactVCard.firstName+" "+contactVCard.lastName+"\n");
			console.log(
				"Tappez '1' pour tout fusionner\n"+
				"Tappez '2' pour tout écraser\n"+
				"Tappez '3' pour ne rien faire\n"
			);

			ask("Votre réponse", /.+/, function(answer) {
				if ( answer == '1' || answer == '2' ) {
					processingContact(answer, data, contactVCard);
				} else if ( answer == '3' ) {
					console.log("Vous souhaitez ne rien faire\n");
					process.exit();
				}
			});
		} else {
			// on enregistre la nouvelle entrée
			console.log(contactVCard.firstName+" "+contactVCard.lastName+" a bien été ajouté!");
			var newData = contactVCard.lastName + ";" + contactVCard.firstName + ";" + contactVCard.phone + ";" + contactVCard.organisation + ";" + contactVCard.state + "\n";
			data += newData;

			fs.writeFile('Base.csv', data, function (err) {
			if (err) 
				return console.log(err);
			});
		}
	});
}

//Fonction pour gérer la saisie au clavier de l'utilisateur
function ask (question, format, callback) {
	var stdin = process.stdin, stdout = process.stdout;

	stdin.resume();
	stdout.write(question + ": ");

	stdin.once('data', function(data) {
		data = data.toString().trim();

		if (format.test(data)) {
		 callback(data);
		} else {
			stdout.write("It should match: "+ format +"\n");
			ask(question, format, callback);
		}
	});
}
